home *** CD-ROM | disk | FTP | other *** search
- /* The following files must be imported. */
- #ifndef UNITGENERATORS_H
- #define UNITGENERATORS_H
-
- #import <musickit/musickit.h>
- #import <musickit/unitgenerators/Add2UGxxx.h>
- #import <musickit/unitgenerators/Add2UGyyy.h>
- #import <musickit/unitgenerators/AsympUGy.h>
- #import <musickit/unitgenerators/DelayUGyxx.h>
- #import <musickit/unitgenerators/Mul2UGyyy.h>
- #import <musickit/unitgenerators/OscgUGyy.h>
- #import <musickit/unitgenerators/OscgafiUGxyyy.h>
- #import <musickit/unitgenerators/Out1aUGx.h>
- #import <musickit/unitgenerators/Out1bUGy.h>
-
- #define MK_OSCFREQSCALE 256.0 /* Used by Oscg and Oscgaf */
- #endif UNITGENERATORS_H
-
- #import "Bark.h"
-
- @implementation Bark:SynthPatch
- {
- id LoochWave;
- }
-
- static int i = 0;
-
- /* A static integer is created for each synthElement. */
- static int osc[2], /* wave UG */
- ampEnvUG, /* amplitude envelope UG */
- ampPatchpoint, /* amplitude patch point */
- freqOscUG[2], /* frequency vibrato UG */
- vibDeviateUG[2], /* base deviation of note */
- vibMulUG[2], /* vibrato increment calculator */
- vibMulIn1[2], /* vib oscil input patch point */
- vibMulIn2[2], /* vib base input patch point */
- vibBaseUG[2], /* base frequency of note */
- freqEnvUG[2], /* frequency of note adder */
- freqEnvIn1[2], /* freq adder input 1 */
- freqEnvIn2[2], /* freq adder input 2 */
- freqPatchpoint[2], /* frequency patch point */
- oscOutPatchpoint[2], /* output of the two oscil chains */
- oscSum, /* add the two oscil chains */
- delayUG, /* digital delay unit generator */
- delayIn, /* delay line input patch point */
- delayOut, /* delay line output patch point */
- stereoOutA, /* sound output UG for channel 0 */
- stereoOutB, /* sound output UG for channel 1 */
- outPatchpointA, /* SynthData */
- outPatchpointB, /* SynthData -- whatever */
- DelayLine; /* SynthData memory for delay */
-
- + patchTemplateFor:aNote
- /* The argument is ignored in this implementation. */
- {
- int DelayLength,j;
-
- /* Step 1: Create an instance of the PatchTemplate class. */
- static id theTemplate = nil;
- // I took this out to give me four different templates for 4 delay lines
- // if (theTemplate)
- // return theTemplate;
- theTemplate = [PatchTemplate new];
-
- /* Step 2: Add synthElement specifications to the PatchTemplate. */
- ampEnvUG = [theTemplate addUnitGenerator:[AsympUGy class]];
- for (j = 0; j < 2; j++) {
- vibBaseUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]];
- vibDeviateUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]];
- freqOscUG[j] = [theTemplate addUnitGenerator:[OscgUGyy class]];
- vibMulUG[j] = [theTemplate addUnitGenerator:[Mul2UGyyy class]];
- freqEnvUG[j] = [theTemplate addUnitGenerator:[Add2UGyyy class]];
- osc[j] = [theTemplate addUnitGenerator:[OscgafiUGxyyy class]];
- }
-
- oscSum = [theTemplate addUnitGenerator:[Add2UGxxx class]];
- delayUG = [theTemplate addUnitGenerator:[DelayUGyxx class]];
- stereoOutA = [theTemplate addUnitGenerator:[Out1aUGx class]];
- stereoOutB = [theTemplate addUnitGenerator:[Out1bUGy class]];
-
- switch(i) {
- case 0:
- DelayLength = 500;
- break;
- case 1:
- DelayLength = 85;
- break;
- case 2:
- DelayLength = 40;
- break;
- case 3:
- DelayLength = 5;
- break;
- default:
- fprintf(stderr,"DelayLength problems!\n");
- DelayLength = 1;
- }
-
- DelayLine = [theTemplate addSynthData:MK_xData length:DelayLength];
-
- ampPatchpoint = [theTemplate addPatchpoint:MK_yPatch];
- for (j = 0; j < 2; j++) {
- vibMulIn1[j] = [theTemplate addPatchpoint:MK_yPatch];
- vibMulIn2[j] = [theTemplate addPatchpoint:MK_yPatch];
- freqEnvIn1[j] = [theTemplate addPatchpoint:MK_yPatch];
- freqEnvIn2[j] = [theTemplate addPatchpoint:MK_yPatch];
- freqPatchpoint[j] = [theTemplate addPatchpoint:MK_yPatch];
- oscOutPatchpoint[j] = [theTemplate addPatchpoint:MK_xPatch];
- }
- delayIn = [theTemplate addPatchpoint:MK_xPatch];
- delayOut = [theTemplate addPatchpoint:MK_yPatch];
- outPatchpointA = [theTemplate addPatchpoint:MK_xPatch];
- outPatchpointB = [theTemplate addPatchpoint:MK_yPatch];
-
- /* Step 3: Specify the connections between synthElements. */
- [theTemplate to:ampEnvUG sel:@selector(setOutput:) arg:ampPatchpoint];
- for (j = 0; j < 2; j++) {
- [theTemplate to:freqOscUG[j] sel:@selector(setOutput:) arg:vibMulIn1[j]];
- [theTemplate to:vibDeviateUG[j] sel:@selector(setOutput:)
- arg:vibMulIn2[j]];
- [theTemplate to:vibMulUG[j] sel:@selector(setInput1:) arg:vibMulIn1[j]];
- [theTemplate to:vibMulUG[j] sel:@selector(setInput2:) arg:vibMulIn2[j]];
- [theTemplate to:vibMulUG[j] sel:@selector(setOutput:) arg:freqEnvIn1[j]];
- [theTemplate to:vibBaseUG[j] sel:@selector(setOutput:) arg:freqEnvIn2[j]];
- [theTemplate to:freqEnvUG[j] sel:@selector(setInput1:) arg:freqEnvIn1[j]];
- [theTemplate to:freqEnvUG[j] sel:@selector(setInput2:) arg:freqEnvIn2[j]];
- [theTemplate to:freqEnvUG[j] sel:@selector(setOutput:)
- arg:freqPatchpoint[j]];
- [theTemplate to:osc[j] sel:@selector(setAmpInput:) arg:ampPatchpoint];
- [theTemplate to:osc[j] sel:@selector(setIncInput:) arg:freqPatchpoint[j]];
- [theTemplate to:osc[j] sel:@selector(setOutput:) arg:oscOutPatchpoint[j]];
- }
- [theTemplate to:oscSum sel:@selector(setInput1:) arg:oscOutPatchpoint[0]];
- [theTemplate to:oscSum sel:@selector(setInput2:) arg:oscOutPatchpoint[1]];
- [theTemplate to:oscSum sel:@selector(setOutput:) arg:outPatchpointA];
- [theTemplate to:stereoOutA sel:@selector(setInput:) arg:outPatchpointA];
- [theTemplate to:delayUG sel:@selector(setInput:) arg:outPatchpointA];
- [theTemplate to:delayUG sel:@selector(setOutput:) arg:outPatchpointB];
- [theTemplate to:stereoOutB sel:@selector(setInput:) arg:outPatchpointB];
- [theTemplate to:delayUG sel:@selector(setDelayMemory:) arg:DelayLine];
-
- /* Always return the PatchTemplate. */
- return theTemplate;
- }
-
- - applyParameters:aNote
- /* This is a private method to the Envy class. It is used internally only.
- */
- {
- /* Retrieve and store the parameters. */
- double myFreq0 = [aNote parAsDouble:MK_freq0];
- double myFreq1 = [aNote parAsDouble:MK_freq1];
- double FreqInc;
- double myAmp = [aNote parAsDouble:MK_amp];
- // double myBearing = [aNote parAsDouble:MK_bearing];
- double myVibFreq0 = [aNote parAsDouble:MK_svibFreq];
- double myVibAmp0 = [aNote parAsDouble:MK_svibAmp];
- double myVibFreq1 = [aNote parAsDouble:MK_rvibFreq];
- double myVibAmp1 = [aNote parAsDouble:MK_rvibAmp];
- double FreqIncHi;
- LoochWave = [aNote parAsWaveTable:MK_waveform];
-
- /* set wavetable if present */
- if (LoochWave != nil) {
- [[self synthElementAt:osc[0]] setTable:LoochWave length:64
- defaultToSineROM:YES];
- [[self synthElementAt:osc[1]] setTable:LoochWave length:64
- defaultToSineROM:YES];
- }
-
- /* Apply frequency if present. */
- if (myFreq0 != MAXDOUBLE) {
- FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0];
- [[self synthElementAt:vibBaseUG[0]] setConstant:FreqInc];
- }
- if (myFreq1 != MAXDOUBLE) {
- FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1];
- [[self synthElementAt:vibBaseUG[1]] setConstant:FreqInc];
- }
-
- /* Apply vibrato freq if present */
- if (myVibFreq0 != MAXDOUBLE) {
- [[self synthElementAt:freqOscUG[0]] setFreq:myVibFreq0];
- }
- if (myVibFreq1 != MAXDOUBLE) {
- [[self synthElementAt:freqOscUG[1]] setFreq:myVibFreq1];
- }
-
- /* Apply vibrato amplitude if present (amp in Hz) */
- if (myVibAmp0 != MAXDOUBLE) {
- FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0];
- FreqIncHi = [[self synthElementAt:osc[0]]
- incAtFreq:(myFreq0+myVibAmp0)];
- [[self synthElementAt:vibDeviateUG[0]]
- setConstant:(FreqIncHi-FreqInc)];
- }
- if (myVibAmp1 != MAXDOUBLE) {
- FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1];
- FreqIncHi = [[self synthElementAt:osc[1]]
- incAtFreq:(myFreq1+myVibAmp1)];
- [[self synthElementAt:vibDeviateUG[1]]
- setConstant:(FreqIncHi-FreqInc)];
- }
-
- /* Apply amplitude if present. */
- if (myAmp != MAXDOUBLE)
- [[self synthElementAt:ampEnvUG] setTargetVal:myAmp];
-
- // /* Apply bearing if present. */
- // if (myBearing != MAXDOUBLE)
- // [[self synthElementAt:stereoOut] setBearing:myBearing];
-
- }
-
- - noteOnSelf:aNote
- {
- /* Step 1: Read the parameters in the Note and apply them to the patch. */
- [self applyParameters:aNote];
-
- [[self synthElementAt:ampEnvUG] setCurVal:0.0];
- [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampAtt]];
-
- /* Step 2: Turn on the patch by connecting the Out2sumUGx object to the
- patchpoint and sending the run message to all the synthElements. */
- [[self synthElementAt:stereoOutA]
- setInput:[self synthElementAt:outPatchpointA]];
- [[self synthElementAt:stereoOutB]
- setInput:[self synthElementAt:outPatchpointB]];
- [synthElements makeObjectsPerform:@selector(run)];
-
- return self;
- }
-
- - noteUpdateSelf:aNote
- {
- [self applyParameters:aNote];
-
- [[self synthElementAt:ampEnvUG] setTargetVal:0.0];
- [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampRel]];
-
- return self;
- }
-
- - (double)noteOffSelf:aNote
- {
- [self applyParameters:aNote];
-
- return 0.0;
- }
-
- - noteEndSelf
- {
- /* Deactivate the SynthPatch by idling the output. */
- [[self synthElementAt:stereoOutA] idle];
- [[self synthElementAt:stereoOutB] idle];
-
- return self;
- }
-
-
- - initialize
- {
- /* Initialize is automatically sent once when an instance is created, after
- it's patch has been loaded. */
- [[self synthElementAt:osc[0]] setTable:nil defaultToSineROM:YES];
- /* full output for vibrato */
- [[self synthElementAt:freqOscUG[0]] setAmp:1.0];
-
- [[self synthElementAt:osc[1]] setTable:nil defaultToSineROM:YES];
- /* full output for vibrato */
- [[self synthElementAt:freqOscUG[1]] setAmp:1.0];
-
- return self;
- }
- @end